/*
 *   A task scheduler that implements Monte-Carlo simulation
 *
 *   Copyright (C) 2011 Systasis Computer Systems, Inc.
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *   
 *   $Id: TestSkedStorage.java 98 2011-08-15 00:45:11Z jchimene@gmail.com $
 */
package com.systasis.sked.client;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Logger;

import com.google.gwt.core.client.EntryPoint;
import com.systasis.sked.client.model.ActivityExporter;
import com.systasis.sked.client.model.SkedStorage;
import com.systasis.sked.client.presenter.Activity;
import com.systasis.sked.client.presenter.ActivityOnNodeScheduler;

public class TestSkedStorage implements EntryPoint {

    private class TaskExporter implements ActivityExporter.Storage {
	StringBuffer stringBuffer = new StringBuffer();

	@Override
	public void addActivityName(String name) {
	    stringBuffer.append('[').append(name).append("] ==> ");
	}

	@Override
	public void addBest(Double best) {
	    stringBuffer.append("best: ").append(best).append(", ");
	}

	@Override
	public void addId(Integer id) {
	    stringBuffer.append("id: ").append(id).append(", ");
	}

	@Override
	public void addLikely(Double likely) {
	    stringBuffer.append("likely: ").append(likely).append(", ");
	}

	@Override
	public void addPredecessorList(ArrayList<Integer> predecessor) {
	    stringBuffer.append("predecessors: ").append(predecessor.toString()).append(", ");
	}

	@Override
	public void addWorst(Double worst) {
	    stringBuffer.append("worst: ").append(worst).append(", ");
	}

	@Override
	public String toString() {
	    return stringBuffer.substring(0, stringBuffer.length() - 2).toString();
	}

	@Override
	public void addResourceName(String resourceName) {
	    // TODO Auto-generated method stub
	    
	}
    }

    private final static Logger logger = Logger.getLogger(TestSkedStorage.class.getName());

    @Override
    public void onModuleLoad() {
	testStorage01();
	testStorage02();

    }

    public void testStorage01() {
	final HashMap<String, String> bmkExport = makeExportBmk();
	final HashMap<String, String> bmkImport = makeImportBmk();

	final ActivityOnNodeScheduler aonSchedulerExporter = new ActivityOnNodeScheduler();
	final ActivityOnNodeScheduler aonSchedulerImporter = new ActivityOnNodeScheduler();

	makeActivityList(aonSchedulerExporter);

	final SkedStorage skedStorage = new SkedStorage();
	for (final Activity activity : aonSchedulerExporter.activityIterable()) {
	    activity.exporterStorage(skedStorage.get());
	    logger.info(skedStorage.toString());
	    assert (skedStorage.toString().equalsIgnoreCase(bmkExport.get(activity.getActivityName())));
	    aonSchedulerImporter.add(Activity.importerStorage(skedStorage.get()));
	}

	TaskExporter activityExporter = new TaskExporter();
	for (final Activity activity : aonSchedulerImporter.activityIterable()) {
	    activity.exporterStorage(activityExporter);
	    logger.info(activityExporter.toString());
	    assert (activityExporter.toString().equalsIgnoreCase(bmkImport.get(activity.getActivityName())));
	    activityExporter = new TaskExporter();
	}
    }

    public void testStorage02() {
	final HashMap<String, String> bmkImport = makeImportBmk();

	final ActivityOnNodeScheduler aonSchedulerExporter = new ActivityOnNodeScheduler();
	final ActivityOnNodeScheduler aonSchedulerImporter = new ActivityOnNodeScheduler();

	makeActivityList(aonSchedulerExporter);

	final SkedStorage skedStorage = new SkedStorage();

	try {
	    skedStorage.getStorageMap().clear();
	} catch (final Exception e1) {
	    e1.printStackTrace();
	}

	for (final Activity activity : aonSchedulerExporter.activityIterable()) {
	    activity.exporterStorage(skedStorage.get());
	    try {
		skedStorage.getStorageMap().put(activity.getActivityName(), skedStorage.toString());
	    } catch (final Exception e) {
		e.printStackTrace();
	    }
	    logger.info(skedStorage.toString());
	}

	try {
	    for (final String r0 : skedStorage.getStorageMap().values()) {
		skedStorage.open(r0);
		aonSchedulerImporter.add(Activity.importerStorage(skedStorage.get()));
	    }
	} catch (final Exception e) {
	    e.printStackTrace();
	}

	TaskExporter activityExporter = new TaskExporter();
	for (final Activity activity : aonSchedulerImporter.activityIterable()) {
	    activity.exporterStorage(activityExporter);
	    logger.info(activityExporter.toString());
	    assert (activityExporter.toString().equalsIgnoreCase(bmkImport.get(activity.getActivityName())));
	    activityExporter = new TaskExporter();
	}
    }

    private void makeActivityList(final ActivityOnNodeScheduler aonSchedulerExporter) {
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(1).activityName("A").random(0.215).likely(6).build());
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(2).activityName("B").random(0.215).likely(2).build());
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(3).activityName("C").follows("1").random(0.215).likely(3).build());
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(4).activityName("D").follows("2").random(0.215).likely(2).build());
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(5).activityName("E").follows("3").random(0.215).likely(4).build());
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(6).activityName("F").follows("4").random(0.215).likely(1).build());
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(7).activityName("G").follows("5").follows("6").random(0.215).likely(1).build());
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(8).activityName("H").follows("7").random(0.215).likely(6).build());
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(9).activityName("I").follows("8").follows("7").random(0.215).likely(3).build());
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(10).activityName("J").follows("8").follows("7").random(0.215).likely(1).build());
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(11).activityName("K").follows("9").follows("10").random(0.215).likely(1).build());
	aonSchedulerExporter.add(new Activity.ActivityBuilder().id(12).activityName("L").follows("11").build());
    }

    private HashMap<String, String> makeExportBmk() {
	final HashMap<String, String> bmkExport = new HashMap<String, String>();
	bmkExport.put("A", "{\"activityName\":\"A\", \"id\":1, \"predecessorList\":[], \"likely\":6, \"worst\":6.6, \"best\":5.4}");
	bmkExport.put("B", "{\"activityName\":\"B\", \"id\":2, \"predecessorList\":[], \"likely\":2, \"worst\":2.2, \"best\":1.8}");
	bmkExport.put("C", "{\"activityName\":\"C\", \"id\":3, \"predecessorList\":[1], \"likely\":3, \"worst\":3.3, \"best\":2.7}");
	bmkExport.put("D", "{\"activityName\":\"D\", \"id\":4, \"predecessorList\":[2], \"likely\":2, \"worst\":2.2, \"best\":1.8}");
	bmkExport.put("E", "{\"activityName\":\"E\", \"id\":5, \"predecessorList\":[3], \"likely\":4, \"worst\":4.4, \"best\":3.6}");
	bmkExport.put("F", "{\"activityName\":\"F\", \"id\":6, \"predecessorList\":[4], \"likely\":1, \"worst\":1.1, \"best\":0.9}");
	bmkExport.put("G", "{\"activityName\":\"G\", \"id\":7, \"predecessorList\":[5,6], \"likely\":1, \"worst\":1.1, \"best\":0.9}");
	bmkExport.put("H", "{\"activityName\":\"H\", \"id\":8, \"predecessorList\":[7], \"likely\":6, \"worst\":6.6, \"best\":5.4}");
	bmkExport.put("I", "{\"activityName\":\"I\", \"id\":9, \"predecessorList\":[8,7], \"likely\":3, \"worst\":3.3, \"best\":2.7}");
	bmkExport.put("J", "{\"activityName\":\"J\", \"id\":10, \"predecessorList\":[8,7], \"likely\":1, \"worst\":1.1, \"best\":0.9}");
	bmkExport.put("K", "{\"activityName\":\"K\", \"id\":11, \"predecessorList\":[9,10], \"likely\":1, \"worst\":1.1, \"best\":0.9}");
	bmkExport.put("L", "{\"activityName\":\"L\", \"id\":12, \"predecessorList\":[11], \"likely\":0, \"worst\":0, \"best\":0}");
	return bmkExport;
    }

    private HashMap<String, String> makeImportBmk() {
	final HashMap<String, String> bmkImport = new HashMap<String, String>();
	bmkImport.put("A", "[A] ==> id: 1, predecessors: [], likely: 6.0, worst: 6.6, best: 5.4");
	bmkImport.put("B", "[B] ==> id: 2, predecessors: [], likely: 2.0, worst: 2.2, best: 1.8");
	bmkImport.put("C", "[C] ==> id: 3, predecessors: [1], likely: 3.0, worst: 3.3, best: 2.7");
	bmkImport.put("D", "[D] ==> id: 4, predecessors: [2], likely: 2.0, worst: 2.2, best: 1.8");
	bmkImport.put("E", "[E] ==> id: 5, predecessors: [3], likely: 4.0, worst: 4.4, best: 3.6");
	bmkImport.put("F", "[F] ==> id: 6, predecessors: [4], likely: 1.0, worst: 1.1, best: 0.9");
	bmkImport.put("G", "[G] ==> id: 7, predecessors: [5, 6], likely: 1.0, worst: 1.1, best: 0.9");
	bmkImport.put("H", "[H] ==> id: 8, predecessors: [7], likely: 6.0, worst: 6.6, best: 5.4");
	bmkImport.put("I", "[I] ==> id: 9, predecessors: [8, 7], likely: 3.0, worst: 3.3, best: 2.7");
	bmkImport.put("J", "[J] ==> id: 10, predecessors: [8, 7], likely: 1.0, worst: 1.1, best: 0.9");
	bmkImport.put("K", "[K] ==> id: 11, predecessors: [9, 10], likely: 1.0, worst: 1.1, best: 0.9");
	bmkImport.put("L", "[L] ==> id: 12, predecessors: [11], likely: 0.0, worst: 0.0, best: 0.0");
	return bmkImport;
    }

}
